home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / asmutil / chasm4.zip / WC.ASM < prev    next >
Assembly Source File  |  1983-11-17  |  10KB  |  315 lines

  1. ;================================================
  2. ; PROGRAM WC    Version 1.1 by Dave Whitman
  3. ;
  4. ; Filter to count words, lines and characters.
  5. ; Based loosely on Kernighan and Ritchie, page 18.
  6. ;
  7. ; Syntax:  WC [/w] [/l] [/c]
  8. ;
  9. ;          /w = unlabeled word count
  10. ;          /l = unlabeled line count
  11. ;          /c = unlabeled character count
  12. ;        none = combined counts, with labels
  13. ;
  14. ; The three options may be present in any combination.
  15. ; Regardless of option order, the selected counts will
  16. ; be in the following order:
  17. ;    words
  18. ;    lines
  19. ;    characters
  20. ;
  21. ; Requires DOS 2.0, will abort under earlier versions.
  22. ;====================================================
  23.  
  24. ;============
  25. ; Equates
  26. ;============
  27.  
  28. @read   equ    3FH             ;read file/device
  29. @chrin  equ    06H             ;get char from stdin
  30. @chrout equ    02H             ;send char to stdout
  31. @dosver equ    30H             ;get dos version
  32. @prnstr equ    09H             ;print string
  33.  
  34. stdin   equ    0000H           ;standard input
  35. w       equ    01H             ;flag value for word option
  36. l       equ    02H             ;flag value for line option
  37. c       equ    04H             ;flag value for char option
  38. yes     equ    0FFH            ;boolean value
  39. no      equ    00H             ;    "
  40. \n      equ    0DH             ;newline char
  41. \t      equ    09H             ;tab char
  42. \l      equ    0AH             ;linefeed char
  43.  
  44. param_count    equ     [80H]
  45. param_area     equ     [81H]
  46.  
  47. main   proc    far
  48.        call    setup           ;check dos, parse options
  49.        call    buf_in          ;count w, l, c from std i/o
  50.        call    output          ;send requested output
  51.        int     20H             ;and return to dos
  52.        endp
  53.  
  54. ;======================================
  55. ; SUBROUTINE SETUP
  56. ; Checks for proper DOS, parses options
  57. ;======================================
  58. setup  proc    near
  59.  
  60.        mov     ah, @dosver     ;what dos are we under?
  61.        int     21H
  62.        cmp     al, 2           ;2.0 or over?
  63.        jae     a1              ;yes, skip
  64.  
  65.        mov     ah, @prnstr     ;no, bitch
  66.        mov     dx, offset(baddos)
  67.        int     21H
  68.        pop     ax              ;reset stack
  69.        int     20H             ;and exit
  70.  
  71. a1     xor     ch,ch           ;cx <== param count
  72.        mov     cl, param_count ;  "
  73.        cmp     cl, 00H         ;any params?
  74.        je      aexit           ;exit if none
  75.  
  76.        mov     di, offset(param_area)   ;scan for options
  77. a2     mov     al, '/'                  ;will be marked with /
  78.        repnz
  79.        scasb
  80.        jnz     aexit           ;reached end
  81.  
  82.        mov     al, [di]        ;get option char
  83.        and     al, 0DFH        ;guarantees upper case
  84.  
  85.        cmp     al, 'W'         ;words?
  86.        jne     a3              ;nope
  87.        orb     options, w      ;yes, set flag
  88.        jmps    a2              ;and loop
  89.  
  90. a3     cmp     al, 'L'         ;lines?
  91.        jne     a4              ;nope
  92.        orb     options, l      ;yes, set flag
  93.        jmps    a2              ;and loop
  94.  
  95. a4     cmp     al, 'C'         ;characters?
  96.        jne     a2              ;nope, just loop
  97.        orb     options, c      ;yes, set flag
  98.        jmps    a2              ;and loop
  99.  
  100. aexit  ret
  101.  
  102. baddos db      'This program requires DOS 2.0!' 0DH, 0AH, '$'
  103.        endp
  104.  
  105. ;=========================================
  106. ; SUBROUTINE BUF_INPUT
  107. ; Inputs data by sector, sends it one char
  108. ; at a time for counting.
  109. ;==========================================
  110.  
  111.  
  112. buf_in proc    near
  113.  
  114.        movb    inword, no      ;not currently in a word
  115.  
  116. bu1    mov     ah, @read       ;read
  117.        mov     bx, stdin       ;from stdin
  118.        mov     cx, 512         ;one sector's worth
  119.        mov     dx, offset(buffer)
  120.        int     21H
  121.        cmp     ax, 00H         ;test for EOF
  122.        jz      buexit          ;if so, done
  123.  
  124.        mov     cx,ax           ;cx <== number chars read
  125.        mov     si, offset(buffer)
  126. bu2    lodsb                   ;al <== next char from buffer
  127.        call    count           ;update totals
  128.        loop    bu2
  129.        jmps    bu1
  130. buexit ret
  131.        endp
  132.  
  133. ;=============================================
  134. ;SUBROUTINE COUNT
  135. ;Counts words, lines and characters as per K&R
  136. ;=============================================
  137. count  proc    near
  138.        addw    clow,0001H      ;bump # of chars
  139.        jae     b1              ;no carry? skip
  140.        incw    chigh           ;handle carry
  141.  
  142.        ;in the following, note use of ADD to increment
  143.        ;doublewords.  INC does not affect Carry Flag.
  144.  
  145. b1     cmp     al, \n          ;is it a newline?
  146.        jne     b2              ;no, skip
  147.        addw    llow,0001H      ;bump # of lines
  148.        jae     b2              ;no carry? skip
  149.        incw    lhigh           ;handle carry
  150.  
  151. b2     cmp     al, \n          ;newline or
  152.        je      b3
  153.        cmp     al, \t          ;tab or
  154.        je      b3
  155.        cmp     al, \l          ;linefeed or
  156.        je      b3
  157.        cmp     al, ' '         ;blank,
  158.        je      b3              ;then skip
  159.  
  160.       ;none of the above
  161.        cmpb    inword, yes     ;already in a word?
  162.        je      b4              ;yes, return
  163.        movb    inword, yes     ;if not, we are now.
  164.        addw    wlow,0001H      ;bump word count
  165.        jae     b4              ;no carry? return
  166.        incw    whigh           ;handle carry
  167.        jmps    b4              ;return
  168.  
  169.       ;any of the above
  170. b3     movb    inword, no
  171. b4     ret
  172.        endp
  173.  
  174. ;=====================================
  175. ; SUBROUTINE OUTPUT
  176. ; Prints results, modified by options.
  177. ;=====================================
  178. output proc    near
  179.  
  180.        cmpb    options, 00H    ;any options?
  181.        jne     c1              ;yes, skip label
  182.        mov     ah, @prnstr     ;print label for word count
  183.        mov     dx, offset(word_label)
  184.        int     21H
  185.        jmps    c1a             ;print count
  186.  
  187. c1     testb   options, W      ;/w option?
  188.        jz      c2              ;nope, skip
  189. c1a    mov     di, whigh       ;get doubleword word count
  190.        mov     si, wlow        ; in di:si
  191.        call    printdd         ;convert and print it.
  192.        call    newline
  193.  
  194. c2     cmpb    options, 00H    ;any options?
  195.        jne     c3              ;yes, skip label
  196.        mov     ah, @prnstr     ;print label for line count
  197.        mov     dx, offset(line_label)
  198.        int     21H
  199.        jmps    c3a             ;print count
  200.  
  201. c3     testb   options, L      ;/l option?
  202.        jz      c4              ;nope, skip
  203. c3a    mov     di, lhigh       ;get doubleword line count
  204.        mov     si, llow        ; in di:si
  205.        call    printdd         ;convert and print it
  206.        call    newline
  207.  
  208. c4     cmpb    options, 00H    ;any options?
  209.        jne     c5              ;yes, skip label
  210.        mov     ah, @prnstr     ;print label for char count
  211.        mov     dx, offset(char_label)
  212.        int     21H
  213.        jmps    c5a             ;print count
  214.  
  215. c5     testb   options, C      ;/c option?
  216.        jz      c6              ;nope, skip
  217. c5a    mov     di, chigh       ;get doubleword char count
  218.        mov     si, clow        ; in di:si
  219.        call    printdd         ;convert and print it
  220.        call    newline
  221.  
  222. c6     ret
  223.  
  224. word_label db 'Words:  $'
  225. line_label db 'Lines:  $'
  226. char_label db 'Chars:  $'
  227.       endp
  228.  
  229. ;=========================
  230. ; SUBROUTINE NEWLINE
  231. ; Prints a CR/LF to stdout
  232. ;=========================
  233. newline proc   near
  234.        mov     ah, @prnstr
  235.        mov     dx, offset(crlf)
  236.        int     21H
  237.        ret
  238. crlf   db      0DH, 0AH, '$'
  239.        endp
  240.  
  241. ;=========================================================
  242. ; SUBROUTINE PRINTDD
  243. ; This less-than-comprehensible routine was swiped verbatim
  244. ; from Ted Reuss's disassembly of John Chapman's sorted
  245. ; disk directory program.  The routine converts a 32 bit
  246. ; integer in DI:SI to ASCII digits and sends them to STDOUT.
  247. ;==========================================================
  248.  
  249. PRINTDD PROC    NEAR    ;Prints a 32 bit integer in DI:SI
  250.         XOR